package com.fy.opengltest.renderPicture;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import android.opengl.GLES20;

import static com.fy.opengltest.ShaderUtils.checkGlError;

public class Circle {

    private static final int sPositionDataSize = 3;
    private static final int sTextureCoordinateDataSize = 2;

    private FloatBuffer mVerticesBuffer;
    private FloatBuffer mTexCoordinateBuffer;
    private ShortBuffer indexBuffer;
    private int mNumIndices;



    public Circle() {
        initVertexData(0f, 0f, 30, 1f);
    }

    private void initVertexData(float offset_x, float offset_y, int sectors, float radius) {
        final int nodeCount = sectors + 2;

        float vertexs[] = new float[nodeCount * 3];
        float texcoords[] = new float[nodeCount * 2];
        short indices[] = new short[nodeCount * 3];

        int offset_texcoord = 0;
        int offset_vertex = 0;
        //for center point
        texcoords[offset_texcoord++] = 0.5f;
        texcoords[offset_texcoord++] = 0.5f;
        vertexs[offset_vertex++] = offset_x;
        vertexs[offset_vertex++] = offset_y;
        vertexs[offset_vertex++] = 0;

        //for circle point
        for (int i = 0; i < sectors + 1; i++) {
            float angleInRadians = ((float) (i) / (float) sectors) * ((float) Math.PI * 2f);

            texcoords[offset_texcoord++] = 0.5f + 0.5f * (float)(Math.sin(angleInRadians));
            texcoords[offset_texcoord++] = 0.5f + 0.5f * (float)(Math.cos(angleInRadians));

            vertexs[offset_vertex++] = offset_x + radius * (float)Math.sin(angleInRadians);
            vertexs[offset_vertex++] = offset_y + radius * (float)Math.cos(angleInRadians);
            vertexs[offset_vertex++] = 0;
        }

        for (int i = 0; i < sectors + 1; i++){
            indices[i * 3] = 0;
            indices[i * 3 + 1] = (short)(i + 1);
            indices[i * 3 + 2] = (short)(i + 2);
        }

        indices[indices.length - 1] = 1;

        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(
                // (# of coordinate values * 4 bytes per float)
                vertexs.length * 4);
        bb.order(ByteOrder.nativeOrder());
        FloatBuffer vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(vertexs);
        vertexBuffer.position(0);

        // initialize vertex byte buffer for shape coordinates
        ByteBuffer cc = ByteBuffer.allocateDirect(
                texcoords.length * 4);
        cc.order(ByteOrder.nativeOrder());
        FloatBuffer texBuffer = cc.asFloatBuffer();
        texBuffer.put(texcoords);
        texBuffer.position(0);

        // initialize byte buffer for the draw list
        ByteBuffer dlb = ByteBuffer.allocateDirect(
                // (# of coordinate values * 2 bytes per short)
                indices.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        indexBuffer = dlb.asShortBuffer();
        indexBuffer.put(indices);
        indexBuffer.position(0);

        mTexCoordinateBuffer=texBuffer;
        mVerticesBuffer=vertexBuffer;
        mNumIndices=indices.length;
    }

    public void uploadVerticesBuffer(int positionHandle){
        FloatBuffer vertexBuffer = getVerticesBuffer();
        if (vertexBuffer == null) return;
        vertexBuffer.position(0);

        GLES20.glVertexAttribPointer(positionHandle, sPositionDataSize, GLES20.GL_FLOAT, false, 0, vertexBuffer);
        checkGlError("glVertexAttribPointer maPosition");
        GLES20.glEnableVertexAttribArray(positionHandle);
        checkGlError("glEnableVertexAttribArray maPositionHandle");
    }

    public void uploadTexCoordinateBuffer(int textureCoordinateHandle){
        FloatBuffer textureBuffer = getTexCoordinateBuffer();
        if (textureBuffer == null) return;
        textureBuffer.position(0);

        GLES20.glVertexAttribPointer(textureCoordinateHandle, sTextureCoordinateDataSize, GLES20.GL_FLOAT, false, 0, textureBuffer);
        checkGlError("glVertexAttribPointer maTextureHandle");
        GLES20.glEnableVertexAttribArray(textureCoordinateHandle);
        checkGlError("glEnableVertexAttribArray maTextureHandle");
    }

    public FloatBuffer getVerticesBuffer() {
        return mVerticesBuffer;
    }

    public FloatBuffer getTexCoordinateBuffer() {
        return mTexCoordinateBuffer;
    }

    public void draw() {
        indexBuffer.position(0);
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, mNumIndices, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
    }
}